package cn.infozr.api.client;

import java.util.List;
import java.util.ArrayList;
import java.util.UUID;
import java.text.SimpleDateFormat;

import cn.infozr.api.util.MD5Util;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;

/**
 * 药品入库信息上传接口客户端
 * 用于测试 https://IP:端口/ygydapi/v1/uploadDrugIn 接口
 */
public class DrugInUploadApiClient extends BaseClient {
    

    
    /**
     * 药品入库信息数据项
     */
    public static class DrugInItem {
        private String ypwybsm;      // 药品唯一标识码
        private String yppzwh;  // 完整的药品批准文号
        private String crklx;        // 入库类型：1采购入库 2退货入库 3其它入库
        private String crksj;        // 入库时间 yyyy-MM-dd HH:mm:ss
//        private String jbr;          // 经办人姓名
        private String scrq;         // 生产日期格式 yyyy-MM-dd
        private String cpph;         // 产品批号
        private String yxqz;         // 有效期至格式 yyyy-MM-dd
        private Double sl;           // 药品数量，按最小计价包装单位统计，保留2位小数
        private Double dj;           // 单价，保留2位小数
//        private String gysmc;        // 供应商名称
//        private String gystyxydm;    // 供应商统一信用代码
        private String ypzsm;        // 药品追溯码，如有多个用英文逗号隔开
        private String bz;           // 备注
        
        // Getters and Setters
        public String getYpwybsm() { return ypwybsm; }
        public void setYpwybsm(String ypwybsm) { this.ypwybsm = ypwybsm; }

        public String getYppzwh() {
            return yppzwh;
        }

        public void setYppzwh(String yppzwh) {
            this.yppzwh = yppzwh;
        }

        public String getCrklx() { return crklx; }
        public void setCrklx(String crklx) { this.crklx = crklx; }
        
        public String getCrksj() { return crksj; }
        public void setCrksj(String crksj) { this.crksj = crksj; }
        
//        public String getJbr() { return jbr; }
//        public void setJbr(String jbr) { this.jbr = jbr; }
        
        public String getScrq() { return scrq; }
        public void setScrq(String scrq) { this.scrq = scrq; }
        
        public String getCpph() { return cpph; }
        public void setCpph(String cpph) { this.cpph = cpph; }
        
        public String getYxqz() { return yxqz; }
        public void setYxqz(String yxqz) { this.yxqz = yxqz; }
        
        public Double getSl() { return sl; }
        public void setSl(Double sl) { this.sl = sl; }
        
        public Double getDj() { return dj; }
        public void setDj(Double dj) { this.dj = dj; }
        
//        public String getGysmc() { return gysmc; }
//        public void setGysmc(String gysmc) { this.gysmc = gysmc; }
//
//        public String getGystyxydm() { return gystyxydm; }
//        public void setGystyxydm(String gystyxydm) { this.gystyxydm = gystyxydm; }
        
        public String getYpzsm() { return ypzsm; }
        public void setYpzsm(String ypzsm) { this.ypzsm = ypzsm; }
        
        public String getBz() { return bz; }
        public void setBz(String bz) { this.bz = bz; }
    }
    
    /**
     * 药品入库信息上传请求参数类
     */
    public static class DrugInUploadRequest {
        private String appId;
        private String timestamp;
        private String reqId;
        private String uscc;
        private String data;
        private String sign;
        
        // 构造函数
        public DrugInUploadRequest() {
            this.timestamp = String.valueOf(System.currentTimeMillis());
        }
        
        // Getters and Setters
        public String getAppId() { return appId; }
        public void setAppId(String appId) { this.appId = appId; }
        
        public String getTimestamp() { return timestamp; }
        public void setTimestamp(String timestamp) { this.timestamp = timestamp; }
        
        public String getReqId() { return reqId; }
        public void setReqId(String reqId) { this.reqId = reqId; }
        
        public String getUscc() { return uscc; }
        public void setUscc(String uscc) { this.uscc = uscc; }
        
        public String getData() { return data; }
        public void setData(String data) { this.data = data; }
        
        public String getSign() { return sign; }
        public void setSign(String sign) { this.sign = sign; }
    }
    
    /**
     * 生成数据签名
     * @param request 请求参数对象
     * @return 签名字符串
     * @throws Exception 加密异常
     */
    protected String generateSign(DrugInUploadRequest request) throws Exception {
        // 按照字段名的字典序拼接参数
        java.util.TreeMap<String, String> params = new java.util.TreeMap<>();
        params.put("appId", request.getAppId());
        params.put("reqId", request.getReqId());
        params.put("timestamp", request.getTimestamp());
        
        if (request.getUscc() != null && !request.getUscc().isEmpty()) {
            params.put("uscc", request.getUscc());
        }
        if (request.getData() != null && !request.getData().isEmpty()) {
            params.put("data", request.getData());
        }
        
        // 注意：根据接口文档，data参数通常不参与签名计算
        // 如果需要参与签名，需要按照接口文档具体要求实现
        
        return cn.infozr.api.util.SM3SignatureUtil.generateSignature(params, SECRET_KEY);
    }
    
    /**
     * 调用药品入库信息上传接口
     * @param uscc 药店18位统一社会信用代码
     * @param data 药品入库信息数据列表
     * @return 接口响应结果
     * @throws Exception 网络或解析异常
     */
    public String uploadDrugIn(String uscc, List<DrugInItem> data) throws Exception {
        // 构造请求参数
        DrugInUploadRequest request = new DrugInUploadRequest();
        request.setAppId(APP_ID);
        request.setTimestamp(String.valueOf(System.currentTimeMillis()));
        request.setUscc(uscc);
        if (data != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            String dataJson = objectMapper.writeValueAsString(data);
            request.setData(dataJson);
            // 传递相同的reqId到服务器，服务器会忽略本次请求 （为防止网格中断导致数据重复上传,建议该值传MD5(数据)）
            String reqId = MD5Util.getMD5(dataJson);
            request.setReqId(reqId);
        }
        
        // 生成签名
        request.setSign(generateSign(request));
        
        // 发送POST请求
        return sendPostRequest(DRUG_IN_API_URL, request);
    }
    
    /**
     * 发送POST请求（重写父类方法以适应新的请求类型）
     * @param url 请求地址
     * @param request 请求参数对象
     * @return 响应结果
     * @throws Exception 网络异常
     */
    protected String sendPostRequest(String url, DrugInUploadRequest request) throws Exception {
        java.net.URL obj = new java.net.URL(url);
        java.net.HttpURLConnection con = (java.net.HttpURLConnection) obj.openConnection();

        // 设置请求方法和请求头
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json; utf-8");
        con.setRequestProperty("Accept", "application/json");
        con.setDoOutput(true);

        // 序列化请求参数，过滤空值
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL);
        String jsonInputString = objectMapper.writeValueAsString(request);
        System.out.println("请求参数: " + jsonInputString);
        
        // 发送请求
        try(java.io.OutputStream os = con.getOutputStream()) {
            byte[] input = jsonInputString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        // 读取响应
        try(java.io.BufferedReader br = new java.io.BufferedReader(
                new java.io.InputStreamReader(con.getInputStream(), "utf-8"))) {
            StringBuilder response = new StringBuilder();
            String responseLine = null;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine.trim());
            }
            return response.toString();
        }
    }
    
    /**
     * 解析并打印上传结果
     * @param jsonResponse JSON响应字符串
     * @throws Exception 解析异常
     */
    public void parseAndPrintUploadResult(String jsonResponse) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(jsonResponse);
        
        System.out.println("接口响应:"+jsonResponse);
        System.out.println("状态码: " + (rootNode.has("code") ? rootNode.get("code").asText() : "无"));
        System.out.println("消息提示: " + (rootNode.has("msg") ? rootNode.get("msg").asText() : "无"));
        System.out.println("请求ID: " + (rootNode.has("reqId") ? rootNode.get("reqId").asText() : "无"));
    }
    
    /**
     * 主方法 - 测试接口调用
     */
    public static void main(String[] args) {
        try {
            DrugInUploadApiClient client = new DrugInUploadApiClient();
            
            // 构造测试数据
            List<DrugInItem> data = new ArrayList<>();
            
            DrugInItem item1 = new DrugInItem();
            item1.setYpwybsm("1021285934992024983");
            item1.setYppzwh("国药准字H20056948");
            item1.setCrklx("1"); // 采购入库
            item1.setCrksj("2025-09-27 12:50:50");
//            item1.setJbr("张三");
            item1.setScrq("2025-01-01");
            item1.setCpph("PH2025010101");
            item1.setYxqz("2027-12-31");
            item1.setSl(200.05);
//            item1.setDj();
//            item1.setGysmc("合肥药业有限公司");
//            item1.setGystyxydm("91340100MA2TQG5H8L");
            item1.setYpzsm("123456789012345678");
            item1.setBz("测试数据");
            data.add(item1);
            
//            DrugInItem item2 = new DrugInItem();
//            item2.setYpwybsm("1346857632788601987");
//            item2.setYppzwh("国药准字H20210053");
//            item2.setCrklx("2"); // 退货入库
//            item2.setCrksj("2025-09-14 12:50:50");
////            item2.setJbr("李四");
//            item2.setScrq("2025-02-01");
//            item2.setCpph("PH2025020101");
//            item2.setYxqz("2027-11-30");
//            item2.setSl(50.00);
//            item2.setDj(30.00);
////            item2.setGysmc("安徽医药有限公司");
////            item2.setGystyxydm("91340200MA2TQG5H8M");
//            item2.setYpzsm("234567890123456789,234567890123456720");
//            item2.setBz("退货测试数据");
//            data.add(item2);
            
            // 测试调用接口
            String result = client.uploadDrugIn(uscc, data);
            
            // 解析并打印结果
            client.parseAndPrintUploadResult(result);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}